//
//  DatabaseManager.m
//  project
//
//  Created by lc on 16/5/19.
//  Copyright © 2016年 lc. All rights reserved.
//


#import "DatabaseManager.h"
//运行时的头文件
#import <objc/runtime.h>
@implementation DatabaseManager{
    FMDatabase *_fmDatabase; // 数据库管理对象
}

- (instancetype)init{
    @throw [NSException exceptionWithName:@"初始化异常" reason:@"不允许通过初始化方法创建对象" userInfo:nil];
}

- (instancetype)initPrivate{
        if (self = [super init]) {
            [self createDB];
        }
    return self;
}

+ (instancetype)defaultManager{
    static DatabaseManager *manager = nil;
    static dispatch_once_t onceToken = 0 ;
    dispatch_once(&onceToken, ^{
        if (!manager) {
            manager = [[self alloc]initPrivate];
        }
    });
    return manager;
}
//创建数据库
- (void)createDB{

    //参数1:找寻目录的名字
    //参数2:在哪个目录下查找,用户目录
    //参数3:是否展开波浪花
    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [searchPaths lastObject];
    NSString *dbPath = [documentPath stringByAppendingString:@"/tinyFortune.db"];
    NSLog(@"dbpath = %@",dbPath);
    
    //创建数据库管理对象
    _fmDatabase = [[FMDatabase alloc]initWithPath:dbPath];
    //打开数据库
    if ([_fmDatabase open]) {
        NSLog(@"创建数据库成功");
    }else{
        NSLog(@"创建数据库失败");
        @throw [NSException exceptionWithName:@"数据库打开失败" reason:@"未必" userInfo:nil];
    }
}

#pragma mark -创建数据库表
- (BOOL)cretatTableFromClass:(Class)tabeleClass{
    //从Class中获取类名
    NSString *tableName = NSStringFromClass(tabeleClass);
    //获取所有属性
    NSArray *propertyArray = [self getAllPropertiesFromClass:tabeleClass];
    
   //SQLite无类型数据库
    //两个字符串之间添加一个逗号
    NSString *filedStr = [propertyArray componentsJoinedByString:@","];
    NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS t_%@ (ID	INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,%@);",tableName,filedStr];
    //执行SQL
      return  [_fmDatabase executeUpdate:sql];
}
#pragma mark - 删除数据
- (BOOL)deleteObject:(id)obj{
    NSString *tableName = NSStringFromClass([obj class]);
    NSString *ID = [obj valueForKey:@"ID"];
    NSString *sql = [NSString stringWithFormat:@"Delete from t_%@ where ID = %@ ",tableName,ID];
    return [_fmDatabase executeUpdate:sql];
}
- (BOOL)deleteAllObject:(Class)tableClass{
    NSString *sql = [NSString stringWithFormat:@"Delete from t_%@ ",tableClass];
    return [_fmDatabase executeUpdate:sql];
}
#pragma mark - 增加数据
- (BOOL)insertObject:(id)obj{
    
    [self cretatTableFromClass:[obj class]];
    NSString *tableName = NSStringFromClass([obj class]);
    
    //所有字段
    NSArray *pro = [self getAllPropertiesFromClass:[obj class]];
    //获取属性值
    NSArray *propValuesArray = [self getAllpropertyValuesFromObject:obj];
    NSString *proStr = [pro componentsJoinedByString:@","];
    NSMutableArray *placeholderArray = [NSMutableArray array];
    for (NSString *prop in propValuesArray) {
        [placeholderArray addObject:@"?"];
    }
    //拼接？
    NSString *placeholderStr = [placeholderArray componentsJoinedByString:@","];
    
    
    NSString *sql =[NSString stringWithFormat:@"Insert into t_%@(%@) VALUES(%@) ;",tableName,proStr,placeholderStr];
    NSLog(@"%@",sql);
    
 return  [_fmDatabase executeUpdate:sql values:propValuesArray error:nil];
}
#pragma mark - 查询所有数据
- (NSArray *)selectAllObjectFromClass:(Class)tableClass{
    NSString *tableName = NSStringFromClass(tableClass);
    NSString *sql = [NSString stringWithFormat:@"Select * from t_%@",tableName];
    NSArray *attributeArray = [self getAllPropertiesFromClass:tableClass];
    //获取结果集
    FMResultSet *set = [_fmDatabase executeQuery:sql];
    
    //创建数组存储所有取出的数据
    NSMutableArray *objectArray = [NSMutableArray array];
    //遍历结果集
    while ([set next]) {
        //根据class信息创建对象
        id objc = [tableClass new];
        for (NSString *str in attributeArray) {
            
            //从结果集中取出数据并为对象赋值
            id columnValue =[set objectForColumnName:str];
            //通过KVC方式为对象的属性赋值
            [objc setValue:columnValue forKey:str];
        }
        //取出ID值(因为ID值并不是成员变量,还需要添加成为成员变量---字段)
//        NSInteger ID = [set intForColumn:@"ID"];
//        
//        [objc setValue:[NSNumber numberWithInteger:ID] forKey:@"ID"];
        [objectArray addObject:objc];
    }
    return [objectArray copy];
}
#pragma mark -判断摸个数据在数据库表中是否存在
- (BOOL)isExistWithObject:(id)obj{
    NSNumber *ID = [obj valueForKey:@"ID"];
    NSString *selectSql = [NSString stringWithFormat:@"Selectc count(*) form t_%@ Where ID = %@",NSStringFromClass([obj class]),ID];
    //执行SQL
    FMResultSet *set = [_fmDatabase executeQuery:selectSql];
    while ([set next]) {
        //判断取出的数据大小
        //因为用count*的sql语句，必然会返回count的键值，所以要判断count是否等于0 
        int columnNum = [set intForColumnIndex:0];
        if (columnNum == 0) {
            return NO ;
        }else{
            return  YES;
        }
    }
    return NO;
}
#pragma mark - Runtime
//通过运行时获取Class中所有的属性
-(NSArray *)getAllPropertiesFromClass:(Class)tableClass{
    NSMutableArray *propertyArray = [NSMutableArray new];
    //获取class中的属性名称
    unsigned int proCount = 0 ;
    //返回值为存储着属性的数组
  objc_property_t *propertyTypeArray = class_copyPropertyList(tableClass, &proCount);
    //循环遍历数组
    for (int i = 0 ; i < proCount; i ++) {
        //从数组中取出数据
        objc_property_t propertyType = propertyTypeArray[i];
        //获取属性名称
       const char *propertyName = property_getName(propertyType);
        NSString *proStr = [NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding];
            [propertyArray addObject:proStr];
        
    }
    return [propertyArray copy];
}



//获取插入SQL语句的字段
- (NSString *)getInsertAttriWithClass:(id)objc{
    //拿到所有的属性名
    NSArray *array =[self getAllPropertiesFromClass:[objc class]];
    //用来拼接字段
    NSMutableString *mStr = [NSMutableString new];
    //遍历所有的属性名
    for(int i = 0; i< array.count;i++){
        if (i != array.count -1) {
            [mStr appendFormat:@"%@,",array[i]];
        }else{
            [mStr appendFormat:@"%@",array[i]];
        }
    }
    return mStr;
}

- (NSString *)getValueWithClass:(id)objc{
    //获取到当前对象的所有属性
    NSArray *array = [self getAllPropertiesFromClass:[objc class]];
    int i = 0;
    //可变字符串用来凭接值
    NSMutableString *str = [NSMutableString new];
    for (NSString *attriNmae in array) {
        id value = [objc valueForKey:attriNmae];
        if (i == array.count - 1) {
            [str appendFormat:@"'%@'",value];
        }else{
            [str appendFormat:@"'%@',",value];
        }
        i++;
    }
    return str;
}
//获取插入sql语句的Value
- (NSArray *)getAllpropertyValuesFromObject:(id)object{
    NSArray *propertyArray = [self getAllPropertiesFromClass:[object class]];
    NSMutableArray *proValuesArray = [NSMutableArray new];
    for (NSString *pro in propertyArray) {
        //通过KVC方式访问获取对象的属性值
        id propValue = [object valueForKey:pro];
        if (!propValue) {
            //如果为空的话需要添加一个空对象
            [proValuesArray  addObject:[NSNull null]];
        }else{
            [proValuesArray addObject:propValue];
        }
    }
    return  [proValuesArray copy];
}

@end
